import { Transaction } from 'tiny-entity2';
import * as Koa from 'koa';
import { Guid, route, RouteOptionsVerify, ServiceManager, Tools } from "../../common";
import { ServiceException } from '../../common/excpetion';
import { ApiDataContext } from '../../domain/apiDataContext';
import { Menu } from '../../domain/models/menu';
import { MenuService } from '../../service/MenuService';
import { PageService } from '../../service/pageService';
import { WorkflowService } from '../../service/workflowService';
const menuSvr = ServiceManager.Current.GetService<MenuService>('MenuService');
const pSvr = ServiceManager.Current.GetService<PageService>('PageService');
const wSvr = ServiceManager.Current.GetService<WorkflowService>('WorkflowService');

class MenuController {
    @route(new RouteOptionsVerify('GET', '/api/menu'))
    async queryMenus(ctx: Koa.Context, next) {
        let params = ctx.query;
        let rootOrgId = ctx.headers['orgid'];
        if (!params.orgId) {
            params.orgId = rootOrgId;
        }

        let result = await menuSvr.QueryMenu(params);

        ctx.response.body = result;
        await next();
    }
    @route(new RouteOptionsVerify('GET', '/api/menu/:id'))
    async getMenuInfoById(ctx: Koa.Context, next) {
        let id = ctx.params.id;
        let menu = await menuSvr.GetMenuById(id);
        ctx.response.body = menu;
        await next();
    }
    @route(new RouteOptionsVerify('POST', '/api/menu'))
    async createMenu(ctx: Koa.Context, next) {
        let rootOrgId = ctx.headers['orgid'];
        let menu: Menu = ctx.request.body;
        menu.orgId = rootOrgId;
        checkData(menu);
        menu.id = Guid.GetGuid();
        menu.isDelete = false;

        let result = await menuSvr.CreateMenu(menu);
        ctx.response.body = result;
        await next();
    }
    @route(new RouteOptionsVerify('PUT', '/api/menu'))
    async updateMenu(ctx: Koa.Context, next) {
        let menu: Menu = ctx.request.body;
        let rootOrgId = ctx.headers['orgid'];
        if (!menu.id) {
            throw new ServiceException('id 不能为空！');
        }
        checkData(menu);
        let menudata = await menuSvr.GetMenuById(menu.id);

        menudata.name = menu.name;
        menudata.isHide = menu.isHide;
        menudata.icon = menu.icon;
        if (!menudata.pageId) {
            menudata.pageId = menu.pageId;
        }
        if (!menudata.workflowId) {
            menudata.workflowId = menu.workflowId;
        }

        let result = await menuSvr.UpdateMenu(menu);
        ctx.response.body = result;

        await next();
    }

    @route(new RouteOptionsVerify('PUT', '/api/menus/index'))
    async updateMenuIndex(ctx: Koa.Context, next) {
        let menus: Menu[] = ctx.request.body;

        await Transaction(new ApiDataContext(), async ctx => {
            for (let item of menus) {
                await menuSvr.UpdateMenuIndex(item, ctx);
            }
        });

        ctx.response.body = menus;

        await next();
    }


    @route(new RouteOptionsVerify('DELETE', '/api/menu/:id'))
    async deleteMenu(ctx: Koa.Context, next) {
        let id = ctx.params.id;
        let result: any;
        await Transaction(new ApiDataContext(), async datactx => {
            let menu = await menuSvr.GetMenuById(id);
            menu.isDelete = true;

            let menuchilid = await menuSvr.QueryMenu({ parentId: menu.id });

            for (let item of menuchilid.list) {
                if (item.workflowId) {
                    await wSvr.DeleteWorkflow(item.workflowId, datactx);
                }
                if (item.pageId) {
                    await pSvr.DeletePageById(item.pageId, datactx);
                }

                await menuSvr.DeleteMenuById(item.id, datactx);
            }

            if (menu.workflowId) {
                await wSvr.DeleteWorkflow(menu.workflowId, datactx);
            }
            if (menu.pageId) {
                await pSvr.DeletePageById(menu.pageId, datactx);
            }

            result = await menuSvr.DeleteMenuById(menu.id, datactx);

            result = menu;

        });
        ctx.response.body = result;
        await next();
    }
}

const checkData = (data: Menu) => {
    if (!data.name) {
        throw new ServiceException('未填写菜单名称！');
    }
    if (!data.orgId) {
        throw new ServiceException('未传入组织编号！');
    }
}